package com.mutouren.modules.organize.dao.impl;

import java.util.ArrayList;
import java.util.Date;
import java.util.List;

import com.mutouren.common.entity.ValidState;
import com.mutouren.common.orm.HibernateHelper;
import com.mutouren.common.orm.HibernateParamer;
import com.mutouren.common.utils.StringUtils;
import com.mutouren.modules.organize.dao.UserDao;
import com.mutouren.modules.organize.model.Department;
import com.mutouren.modules.organize.model.User;

public class UserDaoImpl implements UserDao {

	@Override
	public User get(int id) {
		return HibernateHelper.get(User.class, id);
	}

	@Override
	public void save(User user) {
		user.onSave();
		HibernateHelper.save(user);
	}

	@Override
	public int update(User user) {
		user.onUpdate();
		HibernateHelper.update(user);
		return 0;
	}

	@Override
	public User getByLoginName(String loginName) {
		String sql = "from User a where a.loginName = :loginName";
		List<HibernateParamer> listParam = new ArrayList<HibernateParamer>();
		listParam.add(new HibernateParamer("loginName", loginName));

		return (User) HibernateHelper.selectOnlyOne(sql, listParam);
	}

	@Override
	public int updatePassword(String newPassword, int userId) {
		String sql = "update User a set a.password = :password, a.passwordModifyTime =:passwordModifyTime where a.id = :id";
		List<HibernateParamer> listParam = new ArrayList<HibernateParamer>();
		listParam.add(new HibernateParamer("password", newPassword));
		listParam.add(new HibernateParamer("passwordModifyTime", new Date()));
		listParam.add(new HibernateParamer("id", userId));

		return HibernateHelper.bulkUpdate(sql, listParam);
	}

	@Override
	public int updateLoginTime(int userId) {
		String sql = "update User a set a.lastLoginTime = :lastLoginTime where a.id = :id ";

		List<HibernateParamer> listParam = new ArrayList<HibernateParamer>();
		listParam.add(new HibernateParamer("lastLoginTime", new Date()));
		listParam.add(new HibernateParamer("id", userId));

		return HibernateHelper.bulkUpdate(sql, listParam);
	}

	@Override
	public int setValidState(int id, Byte validState) {
		String sql = "update User a set a.validState = :validState where a.id = :id";

		List<HibernateParamer> listParam = new ArrayList<HibernateParamer>();
		listParam.add(new HibernateParamer("validState", validState));
		listParam.add(new HibernateParamer("id", id));

		return HibernateHelper.bulkUpdate(sql, listParam);
	}

	@Override
	public List<User> findAllChildByDepartment(Department department) {
		String sql = "from User a left join fetch a.department b where "
				+ "(b.parentIdPath like :parentIdPath or a.department = :department) and a.validState != "
				+ ValidState.DELETE.value;

		String parentIdPath = department.buildSelfIdPath() + "%";

		List<HibernateParamer> listParam = new ArrayList<HibernateParamer>();
		listParam.add(new HibernateParamer("parentIdPath", parentIdPath));
		listParam.add(new HibernateParamer("department", department));

		return HibernateHelper.select(sql, listParam);
	}

	@Override
	public List<User> findChildByDeptId(int deptId) {
		String sql = "from User a left join fetch a.department b where a.department.id = :deptId "
				+ "and a.validState != " + ValidState.DELETE.value;

		List<HibernateParamer> listParam = new ArrayList<HibernateParamer>();
		listParam.add(new HibernateParamer("deptId", deptId));

		return HibernateHelper.select(sql, listParam);
	}

	@Override
	public List<User> searchUser(Department department, boolean isCascade, String user) {
		
		List<HibernateParamer> listParam = new ArrayList<HibernateParamer>();
		StringBuilder sqlBuilder = new StringBuilder();
		sqlBuilder.append("from User a left join fetch a.department b where a.validState != " + ValidState.DELETE.value);
		
		if(department != null) {
			String parentIdPath = department.buildSelfIdPath() + "%";
			if(isCascade) {
				sqlBuilder.append(" and (b.parentIdPath like :parentIdPath or a.department = :department)");
				listParam.add(new HibernateParamer("parentIdPath", parentIdPath));
				listParam.add(new HibernateParamer("department", department));
			} else {
				sqlBuilder.append(" and (a.department = :department)");
				listParam.add(new HibernateParamer("department", department));
			}
		}
		
		if(!StringUtils.isEmptyOrWhitespace(user)) {
			
			sqlBuilder.append(" and (a.name = :name or a.loginName = :loginName)");
			listParam.add(new HibernateParamer("name", user));
			listParam.add(new HibernateParamer("loginName", user));
		}
		
		sqlBuilder.append(" order by b.parentIdPath");
		return HibernateHelper.select(sqlBuilder.toString(), listParam);
	}

	@Override
	public int changDepartment(int userId, int deptId) {
		String sql = "update org_User a set a.deptId = :deptId, updateTime=now() where a.id = :id";

		List<HibernateParamer> listParam = new ArrayList<HibernateParamer>();
		listParam.add(new HibernateParamer("deptId", deptId));
		listParam.add(new HibernateParamer("id", userId));

		return HibernateHelper.updateByNativeSql(sql, listParam);
	}

}
